home *** CD-ROM | disk | FTP | other *** search
/ Java Programmer's Toolkit / Java Programmer's Toolkit.iso / applets / dance / classes / floor.jav < prev    next >
Encoding:
Text File  |  1995-10-11  |  13.0 KB  |  499 lines

  1. /*-
  2.  * Copyright (c) 1995 by Georg Hessmann.
  3.  * All Right Reserved.
  4.  *
  5.  * MEXButtonList.java    1.0   25 Aug 95
  6.  *            1.1   13 Sep 95
  7.  *
  8.  */
  9.  
  10. import java.lang.Math;
  11. import java.awt.Color;
  12. import java.awt.Graphics;
  13. import java.awt.Image;
  14. import java.awt.image.*;
  15.  
  16. import Dance;
  17. import Step;
  18. import Foot;
  19.  
  20. /**
  21.  * Floor maintains one dance floor. Normaly two of them are
  22.  * needed. One for the lady and one for the gent.
  23.  *
  24.  * It stores all informations about the steps which are done
  25.  * and draws them.
  26.  *
  27.  * @version 1.1, 13 Sep 1995
  28.  * @author Georg Heßmann
  29.  */
  30. class Floor {
  31.  
  32.   /** size().width of the floor grid */
  33.   public static final int GridXSize = 80;    // Offset zwischen horiz. Linien
  34.   /** size().height of the floor grid */
  35.   public static final int GridYSize = 80;    // Offset zwischen vert. Linien
  36.  
  37.   String Titel;        // Unterschrift
  38.   int    OffsetTitel;    // wie tief unter dem Parket?
  39.  
  40.   boolean is_dame;    // Ist das ein Damen-Parkett?
  41.   boolean debug_lines;    // sollen Hilfslinien gezeichnet werden?
  42.   
  43.   int g_xoff;        // X-Pos. innerhalb des Graphics Contextes
  44.   int g_yoff;        // Y-Pos. innerhalb des Graphics Contextes
  45.  
  46.   int left;        // Abstand vert. Linie nach links
  47.   int right;        // Abstand vert. Linie nach rechts
  48.   int top;        // Abstand horiz. Linie nach oben
  49.   int bottom;        // Abstand horiz. Linie nach unten
  50.   
  51.   int xsize;        // Groesse X-Richtung
  52.   int ysize;        // Groesse Y-Richtung
  53.   int hlines;        // Anzahl horiz. Linien
  54.   int vlines;        // Anzahl vert. Linien
  55.  
  56.   Foot foots;        // Bilder/Funktionen um die Fuesse
  57.  
  58.   float TR_x;        // x-Koo des TR-Pfeiles
  59.   float TR_y;        // y-Koo des TR-Pfeiles
  60.  
  61.   boolean showComment;    // soll der slow/quick-heel/toe String angezeigt werden?
  62.   boolean useCommentHT;    // show heel/toe or time string?
  63.   float   CStr_x;    // x-Koo des slow/quick Strings
  64.   float   CStr_y;    // y-Koo des slow/quick Strings
  65.   int     commentClearWidth;    // length of last displayed string
  66.  
  67.   int clipRect_x1;
  68.   int clipRect_y1;
  69.   int clipRect_x2;
  70.   int clipRect_y2;
  71.  
  72.   Dance app;
  73.  
  74.   int num_steps = 0;        // Wieviele Schritte wurden bereits gesetzt
  75.   int num_steps_painted = 0;    // und wieviele wurden davon schon gezeichnet
  76.  
  77.   Step    step_arr[];    // Array der gesetzten Fuesse
  78.  
  79.   boolean redraw_floor    = true;  // soll der Hintergrund auch neu gezeichnet werden?
  80.  
  81.  
  82.  
  83.   /**
  84.    * Creates a dance floor.
  85.    * @param t titel (lady/gent)
  86.    * @param isd is this the lady-floor?
  87.    * @param gxo left border of the floor relative to the applet origin
  88.    * @param gyo top border of the floor relative to the applet origin
  89.    * @param xsz x-size of the grid
  90.    * @param ysz y-size of the grid
  91.    * @param lborder left border of the grid
  92.    * @param rborder right border of the grid
  93.    * @param tborder top border of the grid
  94.    * @param bborder bottom border of the grid
  95.    * @param f pointer to the foot object
  96.    * @param app pointer to the main applet
  97.    */
  98.   public Floor(String t, boolean isd, int gxo, int gyo,
  99.            int xsz, int ysz,
  100.            int lborder, int rborder, int tborder, int bborder,
  101.            Foot f, Dance app)
  102.   {
  103.     debug_lines = false;    // draw help-lines?
  104.  
  105.     this.app = app;
  106.  
  107.     Titel       = t;
  108.     OffsetTitel = 20;
  109.     
  110.     is_dame = isd;
  111.     
  112.     g_xoff = gxo;
  113.     g_yoff = gyo;
  114.     
  115.     left   = lborder;
  116.     right  = rborder; 
  117.     top    = tborder;
  118.     bottom = bborder;
  119.  
  120.     xsize = left + right  + xsz*GridXSize;
  121.     ysize = top  + bottom + ysz*GridYSize;
  122.  
  123.     hlines = ysz+1;
  124.     vlines = xsz+1;
  125.  
  126.     foots  = f;
  127.  
  128.     num_steps = 0;
  129.     step_arr  = new Step[64];
  130.     
  131.     //if (TRArr == null) TRArr = app.getImage(app.getCodeBase(), "images/TR.gif");
  132.  
  133.     initClipRect();
  134.   }
  135.  
  136.  
  137.   /** Returns the left border of the floor. */
  138.   public int LeftEdge()
  139.   {
  140.     return g_xoff;
  141.   }
  142.  
  143.   /** Returns the right border of the floor */
  144.   public int RightEdge()
  145.   {
  146.     return g_xoff + xsize;
  147.   }
  148.  
  149.   /** Returns the top border of the floor */
  150.   public int TopEdge()
  151.   {
  152.     return g_yoff;
  153.   }
  154.  
  155.   /** Returns the bottom border of the floor */
  156.   public int BottomEdge()
  157.   {
  158.     return g_yoff + ysize + OffsetTitel;
  159.   }
  160.  
  161.   /** Returns the bottom border without the title string of the floor */
  162.   public int BottomEdgeParket()
  163.   {
  164.     return g_yoff + ysize;
  165.   }
  166.  
  167.   /**
  168.    * Gets a position relative to the grid and returns
  169.    * a x-coordinate relative to the applet origin.
  170.    */
  171.   public int CalcXPos(float x)
  172.   {
  173.     return g_xoff + left + (int)(x * GridYSize);
  174.   }
  175.  
  176.   /**
  177.    * Gets a position relative to the grid and returns
  178.    * a y-coordinate relative to the applet origin.
  179.    */
  180.   public int CalcYPos(float y)
  181.   {
  182.     return g_yoff + top + (int)(y * GridXSize);
  183.   }
  184.  
  185.   /** Is this the lady floor? */
  186.   public boolean IsDame()
  187.   {
  188.     return is_dame;
  189.   }
  190.  
  191.   /**
  192.    * Set the position of the dancing direction arrow.
  193.    */
  194.   public void SetTRPos(float x, float y)
  195.   {
  196.     // x, y ist die Spitze des Pfeiles
  197.     TR_x = x;
  198.     TR_y = y;
  199.   }
  200.  
  201.   /**
  202.    * Set the position of the comment (takt/time - heel/toe) string.
  203.    */
  204.   public void SetComStrPos(float x, float y)
  205.   {
  206.     // Koordinate des slow/quick, ... Strings
  207.     CStr_x = x;
  208.     CStr_y = y;
  209.   }
  210.  
  211.   /** Show the takt/time - heel/toe string (after the next repaint()). */
  212.   public void ShowComStr()    { showComment = true;  }
  213.   
  214.   /** Hide the takt/time - heel/toe string (after the next repaint()). */
  215.   public void HideComStr()    { showComment = false; }
  216.  
  217.   /** Use the heel/toe string for the comment field */
  218.   public void useComStrHT()    { useCommentHT = true; }
  219.  
  220.   /** Use the time (quick/slow) string for the comment field */
  221.   public void useComStrTime()    { useCommentHT = false; }
  222.   
  223.  
  224.   /**
  225.    * Do the step s.
  226.    */
  227.   public void doStep(Step s)
  228.   {
  229.     step_arr[num_steps] = s;
  230.  
  231.     num_steps++;
  232.   }
  233.  
  234.   /**
  235.    * Take back one step. Adds this step to the clip
  236.    * rect of this floor.
  237.    * @see Foot#addToClipRect
  238.    */
  239.   public void backStep()
  240.   {
  241.     num_steps--;
  242.     num_steps_painted = num_steps;
  243.     
  244.     /* x1, y1 -- x2, y2 */
  245.     foots.addToClipRect(this, step_arr[num_steps]);
  246.   }
  247.  
  248.   /** Returns the number of steps already set on this floor. */
  249.   public int getNumSteps()          { return num_steps; }
  250.  
  251.   /** Undo all steps on this floor */
  252.   public void clearSteps()           { num_steps = num_steps_painted = 0; }
  253.  
  254.   /** Repaint all steps on the next repaint(). */
  255.   public void repaintAllSteps()       { num_steps_painted = 0; }
  256.  
  257.  
  258.   /** Initialise the clip rect */
  259.   private void initClipRect()
  260.   {
  261.     clipRect_x1 = 10000;
  262.     clipRect_y1 = 10000;
  263.     clipRect_x2 = 0;
  264.     clipRect_y2 = 0;
  265.   }
  266.  
  267.     /* For BackStep: Called from class Floor.
  268.       Creates a clipRect for the next repaint() to redraw
  269.       only as much as needed to erase the removed steps */
  270.  
  271.   /**
  272.    * Add the rect (x1, y1) - (x2, y2) to the clip rect of this floor.
  273.    * Will be called from Foot.addToClipRect() which will be called
  274.    * from Floor.takeBack().
  275.    * @see Foot#addToClipRect
  276.    * @see Floor#takeBack
  277.    */
  278.   public void addToClipRect(int x1, int y1, int x2, int y2)
  279.   {
  280.     if (x1 < clipRect_x1) clipRect_x1 = x1;
  281.     if (y1 < clipRect_y1) clipRect_y1 = y1;
  282.     if (clipRect_x2 < x2) clipRect_x2 = x2;
  283.     if (clipRect_y2 < y2) clipRect_y2 = y2;
  284.   }
  285.  
  286.   /**
  287.    * Setup the clip rect of this floor onto the graphics context g.
  288.    * Than initialize the clip rect of this floor.
  289.    */
  290.   public Graphics installClipRect(Graphics og)
  291.   { 
  292.     Graphics g = og.create();
  293.     
  294.     if (clipRect_x1 < LeftEdge() || clipRect_y1 < TopEdge() ||
  295.     clipRect_x2 > RightEdge() || clipRect_y2 > BottomEdgeParket()) {
  296.  
  297.       int cx1 = 0, cy1 = 0, cx2 = 0, cy2 = 0;
  298.  
  299.       if (clipRect_x1 < LeftEdge() || RightEdge() < clipRect_x2) {
  300.           if (clipRect_x1  < LeftEdge()) cx1 = clipRect_x1;
  301.     else                    cx1 = RightEdge();
  302.  
  303.     if (RightEdge()  < clipRect_x2) cx2 = clipRect_x2;
  304.     else                     cx2 = LeftEdge();
  305.  
  306.     cy1 = clipRect_y1;
  307.     cy2 = clipRect_y2;
  308.  
  309.     g.clearRect(cx1, cy1, cx2 - cx1, cy2 - cy1);
  310.       }
  311.  
  312.       if (clipRect_y1 < TopEdge() || BottomEdgeParket() < clipRect_y2) {
  313.     if (clipRect_y1  < TopEdge())  cy1 = clipRect_y1;
  314.     else                    cy1 = BottomEdgeParket();
  315.  
  316.     if (BottomEdgeParket() < clipRect_y2) cy2 = clipRect_y2;
  317.     else                       cy2 = TopEdge();
  318.  
  319.           cx1 = clipRect_x1;
  320.     cx2 = clipRect_x2;
  321.  
  322.     g.clearRect(cx1, cy1, cx2 - cx1, cy2 - cy1);
  323.       }
  324.     }
  325.     
  326.     g.clipRect(clipRect_x1, clipRect_y1,
  327.            clipRect_x2 - clipRect_x1, clipRect_y2 - clipRect_y1);
  328.  
  329.     initClipRect();
  330.  
  331.     return g;
  332.   }
  333.   
  334.  
  335.   
  336.   private void paintBackground(Graphics g)
  337.   {
  338.     redraw_floor = false;
  339.     
  340.     g.setColor(Color.white);
  341.     g.fillRect(g_xoff, g_yoff, xsize, ysize);
  342.     g.setColor(Color.black);
  343.  
  344.     int x, y;
  345.  
  346.     // DEBUG LINIEN
  347.     if (debug_lines) {
  348.       g.setColor(Color.lightGray);
  349.       // zeichne die vertikalen Linien
  350.       for (y=1; y<(vlines-1)*10; y++) {
  351.     if (y % 10 != 0) {
  352.       g.drawLine(g_xoff+left + (int)((float)y*(float)GridYSize/10.0f), g_yoff+top,
  353.              g_xoff+left + (int)((float)y*(float)GridYSize/10.0f), g_yoff+ysize-bottom);
  354.     }
  355.       }
  356.       // zeichne die vertikalen Linien
  357.       for (x=0; x<(hlines-1)*10; x++) {
  358.     if (x % 10 != 0) {
  359.       g.drawLine(g_xoff+left,        g_yoff+top + (int)((float)x*(float)GridXSize/10.0f),
  360.              g_xoff+xsize-right, g_yoff+top + (int)((float)x*(float)GridXSize/10.0f));
  361.     }
  362.       }
  363.       g.setColor(Color.black);
  364.      // DEBUG LINIEN
  365.     }
  366.  
  367.     // zeichne die vertikalen Linien
  368.     if (!debug_lines) g.setColor(Color.darkGray);
  369.     for (y=0; y<vlines; y++) {
  370.       g.drawLine(g_xoff+left + y*GridYSize, g_yoff+top,
  371.          g_xoff+left + y*GridYSize, g_yoff+ysize-bottom);
  372.     }
  373.     // zeichne die vertikalen Linien
  374.     for (x=0; x<hlines; x++) {
  375.       g.drawLine(g_xoff+left,        g_yoff+top + x*GridXSize,
  376.          g_xoff+xsize-right, g_yoff+top + x*GridXSize);
  377.     }
  378.     if (!debug_lines) g.setColor(Color.black);
  379.  
  380.     // Unterschrift ausgeben
  381.     int lt = g.getFontMetrics().stringWidth(Titel);
  382.     g.drawString(Titel, g_xoff + (xsize-lt)/2, g_yoff + ysize + OffsetTitel);
  383.  
  384.     // TR-Pfeil zeichnen
  385.     if (!debug_lines) g.setColor(Color.darkGray);
  386.     x = CalcXPos(TR_x);
  387.     y = CalcYPos(TR_y); // + TRArr.getHeight() - 5;    // -1 beachten!!!
  388.     int y2 = CalcYPos((float)Math.floor(TR_y) + 0.9f);
  389.     g.drawLine(x, y, x, y2);
  390.  
  391.     //g.drawImage(TRArr, x-TRArr.getWidth()/2, y-TRArr.getHeight()+5, this); // !!!
  392.     
  393.     g.drawLine(x-4, y+5, x, y);
  394.     g.drawLine(x+4, y+5, x, y);
  395.  
  396.     if (app.engl) g.drawString("D.D.", x+7, y+17);
  397.     else          g.drawString("T.R.", x+7, y+17);
  398.     
  399.     if (!debug_lines) g.setColor(Color.black);
  400. }
  401.  
  402.   /**
  403.    * Draw the floor.
  404.    * If Floor.RedrawFloor() was called, all will be painted.
  405.    * Else only the changed things.
  406.    *
  407.    * @see Floor#RedrawFloor
  408.    */
  409.   public void paint(Graphics g)
  410.   {
  411.     boolean state_drawn = false;
  412.     
  413.     if (redraw_floor) paintBackground(g);
  414.  
  415.     if (foots != null) {
  416.  
  417.       Color fg = g.getColor();
  418.       g.setColor(Color.white);
  419.       g.fillRect(CalcXPos(CStr_x), CalcYPos(CStr_y)-g.getFont().getSize(),
  420.          commentClearWidth, g.getFont().getSize()+4);
  421.       g.setColor(fg);
  422.  
  423.       /* zeichnen der Fuesse */
  424.       for (int i=0; i<num_steps_painted; i++) {
  425.     state_drawn |= foots.redrawFoot(g, this, step_arr[i]);
  426.       }
  427.  
  428.       for (int i=num_steps_painted; i<num_steps; i++) {
  429.     state_drawn |= foots.drawFoot(g, this, step_arr[i]);
  430.       }
  431.  
  432.       /* Anzeige des slow/quick Strings. Geloescht wird er auf jeden Fall. */
  433.       if (commentClearWidth == 0) commentClearWidth = 25;
  434.     
  435.       if (showComment && num_steps > 0) {
  436.     if (useCommentHT) {
  437.       if (step_arr[num_steps-1].ht_id >= 0) {
  438.         String s = Figur.HT_str[app.engl ? 0 : 1][step_arr[num_steps-1].ht_id];
  439.         commentClearWidth = g.getFontMetrics().stringWidth(s);
  440.         g.drawString(s, CalcXPos(CStr_x), CalcYPos(CStr_y));
  441.       }
  442.     }
  443.     else {
  444.       if (step_arr[num_steps-1].takt_str != null) {
  445.         String s = step_arr[num_steps-1].takt_str;
  446.         commentClearWidth = g.getFontMetrics().stringWidth(s);
  447.         g.drawString(s, CalcXPos(CStr_x), CalcYPos(CStr_y));
  448.       }
  449.     }
  450.       }
  451.            
  452.       num_steps_painted = num_steps;
  453.       
  454.       if (state_drawn) {
  455.     for (int i=0; i<2; i++) {
  456.       for (int j=0; j<2; j++) {
  457.         for (int k=0; k<2; k++) {
  458.           for (int l=0; l<16; l++) {
  459.         if (Foot.FootState[i][j][k][l] == Foot.IMG_DRAWN) {
  460.           Foot.FootState[i][j][k][l] = Foot.IMG_OK;
  461.         }
  462.           }
  463.         }
  464.       }
  465.     }
  466.       }
  467.       
  468.     }
  469.   }
  470.  
  471.   /**
  472.    * Next time Floor.paint() will be called, all (floor and steps)
  473.    * will be painted new.
  474.    *
  475.    * @see Floor#paint
  476.    * @see Floor#repaintAllSteps
  477.    */
  478.   public void RedrawFloor()
  479.   {
  480.     redraw_floor = true;
  481.     repaintAllSteps();
  482.   }
  483.  
  484.  
  485.   /**
  486.    * Returns a String object representing.
  487.    */
  488.   public String toString()
  489.   {
  490.     return getClass().getName() + "[Titel=" + Titel + ", Steps=" + num_steps +
  491.               ", Steps-drawn=" + num_steps_painted +
  492.         ", redraw-all=" + redraw_floor + "]";
  493.   }
  494.  
  495.  
  496. }    
  497.  
  498.  
  499.